
<template>
  <div class="pa ui-countdown">
   <span :class="linebreak">距离{{jieduan}}结束还有：</span>
    <span class="lday">{{tt.days}}</span>天
    <span class="lhour">{{tt.hours}}</span>时
    <span class="lmin">{{tt.minutes}}</span>分
    <span class="lsec">{{tt.seconds}}</span>秒 
  </div>
</template>
<style type="text/css" lang="less" scoped>
  .ui-countdown{
    font-size: 1.6rem;
    color: #fff;
    text-align: center;
    .linebreak{
      display: block;
    }
  }
</style>
<script>
import {post,get} from '../public/js/utils.js'
import Swal from 'sweetalert'
export default {
  data:function () {
    this.init()
    return {
      jieduan:'公测',
      tt:{
        days:'**',
        hours:'**',
        minutes:'**',
        seconds:'**',
      },
    }
  },
  props:['linebreak'],
  components:{
  },
  methods:{
    init:async function (){
          const self = this;
          var timer,__reload =10 + Math.floor( Math.random() *10 ),__dis=0;
          var local_server_delta = 0 , c= 0,starstate=1;
          var disTime = 0, disTime2 = 0;
          function toDouble(obj) {
              if (obj < 10) { return '0' + obj }
              else { return obj };
          }

          // 精度是秒，不足一秒的补足为一秒
          function parseAsSeconds(delta_milliseconds) {
            delta_milliseconds = Math.ceil( Math.abs(Number(delta_milliseconds)) /1000 );
            return {
              days: toDouble(Math.floor(delta_milliseconds / 86400)),
              hours: toDouble(Math.floor(delta_milliseconds / 3600) % 24),
              minutes: toDouble(Math.floor(delta_milliseconds / 60) % 60),
              seconds: toDouble(Math.floor(delta_milliseconds) % 60),
            };
          }
          // 获取服务器时间与本地时间的差
          function get_local_server_delta(url, callback) {
              var xhr = new XMLHttpRequest(),
                  request_time, response_time,
                  timer = setTimeout(function() {
                      xhr.abort();
                  }, 3E3); // 3s 超时

              xhr.onreadystatechange = function() {
                  // console.log(xhr.readyState) // 2,3,4
                  if (xhr.readyState == 2) {
                      response_time = new Date().getTime();
                  } else if (xhr.readyState == 4) {
                      clearTimeout(timer);
                      if (xhr.status == 200) {
                          // responseText 返回的是微秒，x1000 得到毫秒
                          callback(Math.floor(1000 * Number(xhr.responseText)) + (response_time - request_time) / 2 - response_time);
                      }
                  }
              }

              xhr.open("get", url, true);
              request_time = new Date().getTime();
              xhr.send(null);
          }

          var timezonediff = (new Date().getTimezoneOffset() + 480)*60000; // 转为东八区

          // 缓存数据，size：最多保存数量，默认10个
          function cache(size){
            this.size = size || 10;
            this.__cache__ = [];
          }

          // 添加数据
          cache.prototype.add = function(data){
            this.__cache__.push(data);
            if(this.__cache__.length > this.size){
              this.__cache__.shift();
            }
          }

          // 情况缓存
          cache.prototype.clean = function(){
            this.__cache__ = [];
          }

          // 获取缓存的数据
          cache.prototype.get = function(){
            return this.__cache__;
          }


          // 记录倒计时日志
          var timer_log = {
            installed: false,
            locked : false, // 锁定时不提交日志
            cacher: new cache(10),
            log:{
              ok:0,no:0,
            },
            delta_cache: 1E12,
            
            // 验证数据
            check: function(delta){
              // return false;
              return this.delta_cache >= delta;
            },
            // 验证失败后执行
            error:function(){
              this.log.no ++;
              if(!this.locked){ // 未锁定
                this.locked = true;

                // 收集数据
                var __data__ = {
                  cache:this.cacher.get(), // 最近10次数据
                  log:this.log, // 执行结果记录
                  local_server_delta:local_server_delta,
                  timezonediff: timezonediff,
                  disTime:disTime,
                  disTime2:disTime2,
                  useridcard:useridcard,
                  createAt:new Date().getTime(),
                };

                this.send(__data__,'time.rollback'); // 时间抖动问题
                setTimeout(function(){
                  timer_log.locked = false; // 10秒后解锁
                },1E4);
              }
            },
            // 验证成功后执行
            success: function(){
              this.log.ok ++;
            },
            // 入口
            go: function(delta){
              if(!this.installed){ // 初始化
                this.delta_cache = delta;
                this.installed = true;
                this.locked = false;

                // this.send({
                //   c:c,timer:timer,
                //   delta:delta,
                //   local_server_delta:local_server_delta,
                //   timezonediff: timezonediff,
                //   disTime:disTime,
                //   disTime2:disTime2,
                //   useridcard:useridcard,
                //   createAt:new Date().getTime(),
                // },'time.installed'); // 时间初始化日志
                return;
              }
              // 对近期数据进行缓存
              this.cacher.add({
                c:c,timer:timer,
                delta:delta,
                delta_cache:this.delta_cache,
                timestamp:new Date().getTime(),
              });

              // 相差时间应该越来越小，如果上次的时间差比这次的小表示有问题发生
              if(!this.check( delta) ){ 
                this.error();
              }else{
                this.success();
              }
              // 缓存上次时间差数据
              this.delta_cache = delta;
            },
            // 发送日志数据到服务器
            send: function(content,type){
              console.log('send log')
              // $.ajax({
              //   url: './webservices/index.path.php/Log/error/',type:'POST',data:{
              //     content:JSON.stringify(content),type:type
              //   } ,dataType:'json',success:function(data){

              //   } ,error:function(e){
              //     console.error('log error error:'+JSON.stringify(e));
              //   }
              // });
            },
          };
          function loop(){
            var local_tt = new Date().getTime() + local_server_delta;
            // console.log('loop:'+disTime+':'+disTime2+':'+local_tt)
              if(local_tt < disTime){ // 未开始
                 notstart(disTime - local_tt);
              }else if(local_tt<disTime2){
                ongoing(disTime2 - local_tt);
              }else{
                  hasover();
              }

              c++;
              if(c%600==0){ // 0.1s 执行一次，60秒需要执行 600 次
                  get_local_server_delta('/public/microtime',function(dt){
                      local_server_delta = dt;
                      c = 0;
                  });
              }
          }
          function filter(start,end,now){
            disTime = start - timezonediff;
            disTime2 = end - timezonediff;
            get_local_server_delta('/public/microtime',function(dt){
              local_server_delta = dt;
              loop();
            });
          }

          // 未开始倒计时
          function notstart(delta){
            timer_log.go(delta);
            if (delta < 0) { // 倒计时结束
                clearTimeout(timer);
                loop(0);
                return;
            }
            var tt = parseAsSeconds(delta);
            self.tt = tt;
            // console.log(tt);
            // $('.ui-countdown').html('<span>距离'+jieduan+
            //   '开始还有：</span> <span class="lday">'+
            //   toDouble(tt.days)+'</span>天 <span class="lhour">'+
            //   toDouble(tt.hours)+'</span>时 <span class="lmin">'+
            //   toDouble(tt.minutes)+'</span>分 <span class="lsec">'
            //   +toDouble(tt.seconds)+'</span>秒');

            // $('#btn-buy').show().unbind('click').bind('click',function(e){
            //   swal('','还未开始，请耐心等待。','error');
            // });

            // 以前的全局变量
            starstate = 0;
            has_start=false;
            timer = setTimeout(loop, 100);
          }

          function ongoing(delta){
            // console.log('delta:'+delta)
            timer_log.go(delta);
            if (delta < 0) { // 倒计时结束
                clearTimeout(timer);
                loop(0);
                return;
            }
            var tt = parseAsSeconds(delta);
            self.tt = tt;
            // console.log(tt);
            // $('.ui-countdown').html('<span >距离'+jieduan+
            //   '结束还有：</span> <span class="lday">'+
            //   toDouble(tt.days)+'</span>天 <span class="lhour">'+
            //   toDouble(tt.hours)+'</span>时 <span class="lmin">'+
            //   toDouble(tt.minutes)+'</span>分 <span class="lsec">'
            //   +toDouble(tt.seconds)+'</span>秒');
            
            // $('#btn-buy').show().unbind('click').bind('click',function(e){
            //   // 判断未认筹 认购次数等信息
            //   modules.house(modules.buy.notice);
            //   // modules.buy.notice();
            // });

            starstate = 1;
            
            timer = setTimeout(loop, 100);
          }

          function hasover(){
            console.log('end')
            // $('.ui-countdown').html(jieduan+'已结束！');
            // starstate = -1;
            // $('#btn-buy').show().unbind('click').bind('click',function(e){
            //   sweetAlert('','对不起，'+jieduan+'已结束！感谢您的关注！','error');
            // });
          }

          // 时间：字符串转数字
          function str2time(str){
            var ary = str.split(',');
            return new Date(ary[0], ary[1]-1, ary[2], ary[3], ary[4], ary[5]).getTime();
          }
          // 获取开始结束时间
          // function tms(){
          //   $.ajax({ 
          //     url:'time.php',data:{type:'timerange'},dataType:'json',success:function(res){
          //       if(timer) clearInterval(timer);
          //       jieduan = res.jd.showName;
          //       g_stage = res.jd;
          //       g_proCode = res.proCode;
          //       TABLE_TAIL = '_'+res.proCode;
          //       filter(str2time(res.startime),str2time(res.endtime),str2time(res.nowtime) );
          //     }
          //   });
          // }
          
          // tms();
          filter(str2time('2018,2,5,10,00,22'),str2time('2019,3,7,24,00,33'),str2time('2018,03,12,18,56,37') );
    },
    jump: function (compName, data){
      this.$root.chgComp(compName, data)
    }
  }

}
</script>
